package getter

import (
	"server/game/itypes"
	"server/game/model"
	"server/share"
	"server/share/config"
	"server/social"
	"server/social/graph"
	"strings"

	"github.com/hwcer/cosgo/registry"
	"github.com/hwcer/cosgo/slice"
	"github.com/hwcer/yyds"
	"github.com/hwcer/yyds/context"
	"github.com/hwcer/yyds/errors"
	"github.com/hwcer/yyds/options"
	"github.com/hwcer/yyds/players/player"
)

func init() {
	Register(&role{})
	options.OAuth.Set(options.ServiceTypeGame, "getter/role/ladder", options.OAuthTypeOAuth)
}

/*
getter 数据获取
*/

type role struct {
}

func (this *role) Caller(node *registry.Node, handle *context.Context) interface{} {
	f := node.Method().(func(*role, *context.Context) interface{})
	return f(this, handle)
}

/**
 * @name ladder
 * @param string uid 玩家唯一标识,多个以","分割
 * @param int lineupId 编组id
 * 对手编组详情
 * @tip 包含数据 fs:编组战力，hero:[{id,lv,slv,blv}...]武将信息 equip:[{}]
 */
func (this *role) Ladder(c *context.Context) interface{} {
	uid := c.GetString("uid")
	if uid == "" {
		return errors.ErrArgEmpty
	}
	lineupId := c.GetInt32("lineupId")
	if _, ok := config.Data.Team[lineupId]; !ok {
		return errors.ErrConfigEmpty
	}
	s := strings.Split(uid, ",")
	m := c.Mutex()
	if r, err := m.Lock(s, lineupId, this.locker); err != nil {
		return err
	} else {
		return r
	}
}

func (this *role) locker(locker player.Locker, args any) (any, error) {
	id, _ := args.(int32)
	if id == 0 {
		return nil, errors.ErrArgEmpty
	}
	r := map[string]any{}
	var err error
	locker.Range(func(player *player.Player) bool {
		uid := player.Uid()
		r[uid] = this.player(player, id)
		return true
	})
	return r, err
}

// 获取
func (this *role) player(player *player.Player, team int32) any {
	return true
}

/*
*

  - @name

  - @param string uid 玩家唯一标识,多个以","分割

  - 玩家简单列表

lastLikeTime
*/

type SimpleReplay struct {
	Role         *SimplePlayer
	Teams        []*model.Teams
	LastLikeTime int64 `json:"lastLikeTime"`
}

// 未知字段  deadArea spaceProgress

type SimplePlayer struct {
	share.Player    `bson:"inline"`
	Like            int64             `json:"like,omitempty" bson:"like"` //点赞
	Defense         int32             `json:"Defense" bson:"Defense"`
	IconFrame       int32             `json:"iconFrame,omitempty" bson:"iconFrame"`
	BattleArea      string            `json:"battleArea,omitempty" bson:"battleArea"`
	RestArea        string            `json:"restArea,omitempty" bson:"restArea"`
	NewStage        map[int32]int32   `json:"NewStage,omitempty" bson:"NewStage"`
	AchievementBall []int32           `json:"achievementBall,omitempty" bson:"achievementBall"` //成就球 原类型[]string
	Create          int64             `json:"create,omitempty" bson:"create" `                  //创建时间
	Package         int32             `json:"package,omitempty" bson:"package"`                 //成就包装袋
	SpaceUnit       int32             `json:"spaceUnit,omitempty" bson:"spaceUnit"`             //个人空间助理
	Update          int64             `json:"update,omitempty" bson:"lastTime" `                //最后更新时间
	Arena           *model.RoleArena  `json:"arena,omitempty" bson:"Arena"`
	Online          int64             `json:"online,omitempty" bson:"online"` //是否在线，
	SpaceProgress   []int32           `json:"spaceProgress,omitempty" bson:"spaceProgress" `
	HelpUnit        model.RoleHelpMgr `json:"helpUnit" bson:"helpUnit"` //助阵列表
}

func (this *role) Simple(c *context.Context) interface{} {
	s := c.GetString("uid")
	//key := c.GetString("key")
	if s == "" {
		return c.Error("uid empty")
	}
	ids := slice.Split(s, ",")
	ids = slice.Unrepeated(ids)
	if len(ids) == 0 {
		return c.Error("uid empty")
	}

	sp := &share.Player{}
	tx := model.DB().Model(&model.Role{}).Where(ids)
	tx = tx.Select(sp.GetDBFields()...)
	tx = tx.Select("iconFrame", "like", "Defense", "helpUnit")

	tx = tx.Select("exp", "battleArea", "restArea", "deadArea", "NewStage", "achievementBall", "create")
	tx = tx.Select("package", "spaceUnit", "lastTime", "arena", "spaceProgress")

	//if key != "" {
	//	arr := strings.Split(key, ",")
	//	for _, v := range arr {
	//		if v != "" {
	//			tx = tx.Select(v)
	//		}
	//	}
	//}
	reply := map[string]*SimpleReplay{}

	var rs []*SimplePlayer
	if tx = tx.Find(&rs); tx.Error != nil {
		return tx.Error
	}
	for _, v := range rs {
		reply[v.Uid] = &SimpleReplay{Role: v}
	}
	if len(reply) == 0 {
		return reply
	}
	//查询所有防守编队
	var teams []string
	for _, v := range rs {
		if v.Defense > 0 {
			if k, err := itypes.Teams.UUID(v.Uid, v.Defense); err == nil {
				teams = append(teams, k)
			}
		}
	}
	if len(teams) > 0 {
		var ts []*model.Teams
		if err := model.DB().Where(teams).Find(&ts).Error; err != nil {
			return err
		}

		for _, v := range ts {
			k := v.Uid
			if p := reply[k]; p != nil {
				p.Teams = append(p.Teams, v)
			}
		}
	}

	social.Graph.RLock(func(stmt graph.Statement) {
		p := stmt.Get(c.Uid())
		for k, v := range reply {
			v.LastLikeTime = p.Likes[k]
			if t := stmt.Get(k); t != nil {
				v.Role.Online = t.Values.GetInt64("online")
			}
		}
	})

	//social.Graph.Reader(c.Uid(), func(p *graph.Player) {
	//	for k, v := range reply {
	//		v.LastLikeTime = p.Likes[k]
	//	}
	//})

	return reply
}

/**
 * @name GetUnitAndChip
 * @param string unitList 单位的唯一标识,多个以","分割
 * 根据单位获取战斗相关的信息
 */

func (this *role) GetUnitAndChip(c *context.Context) interface{} {
	args := c.GetString("unitList")
	if args == "" {
		return errors.ErrArgEmpty
	}
	arr := slice.Unrepeated(slice.Split(args, ","))
	if len(arr) == 0 {
		return errors.ErrArgEmpty
	}
	reply := map[string]any{}
	var unitList []*model.Items
	if err := model.DB().Where(arr).Find(&unitList).Error; err != nil {
		return err
	}
	reply["unitList"] = unitList

	var chip []string
	for _, v := range unitList {
		if !yyds.Config.Is(v.IID, config.ITypeUnit) {
			return c.Errorf(0, "not unit")
		}
		equip := map[int32]string{}
		if err := v.Attach.Unmarshal(model.AttachUnitChipList, &equip); err != nil {
			return err
		}
		for _, u := range equip {
			chip = append(chip, u)
		}
	}

	var chipList []*model.Items
	if len(chip) > 0 {
		if err := model.DB().Where(chip).Find(&chipList).Error; err != nil {
			return err
		}
	}

	reply["chipList"] = chipList

	return reply

}

//Info 使用uid||guid查询一个角色信息

func (this *role) Info(c *context.Context) interface{} {

	args := struct {
		Uid  string `json:"uid"`
		Guid string `json:"guid"`
	}{}
	if err := c.Bind(&args); err != nil {
		return err
	}
	tx := db.Model(&model.Role{})
	if args.Uid != "" {
		tx = tx.Where(args.Uid)
	} else if args.Guid != "" {
		tx = tx.Where("guid = ?", args.Guid)
	} else {
		return errors.ErrArgEmpty
	}
	p := &share.Player{}
	tx = tx.Select(p.GetDBFields()...)
	if err := tx.Find(p).Error; err != nil {
		return err
	}
	return p

}
